package com.nantong.admin.service.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import com.nantong.admin.domain.SalesOrder;
import com.nantong.admin.domain.model.request.salesorder.SalesOrderSearch;
import com.nantong.admin.domain.model.request.salesorder.SalesStatisticsSearch;
import com.nantong.admin.domain.model.response.salesorder.SalesOrderVo;
import com.nantong.admin.domain.model.response.salesorder.SalesStatisticsVo;
import com.nantong.admin.mapper.CustomerMapper;
import com.nantong.admin.mapper.SalesOrderMapper;
import com.nantong.admin.mapper.SysUserMapper;
import com.nantong.admin.service.ISalesOrderService;
import com.nantong.admin.util.LoginHelper;
import com.nantong.common.core.enums.commonEnums.SalesOrderStatusEnum;
import com.nantong.common.core.exception.ServiceException;
import com.nantong.common.core.utils.StringUtils;
import com.nantong.common.mybatis.core.page.PageQuery;
import com.nantong.common.mybatis.core.page.TableDataInfo;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 销售订单Service实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SalesOrderServiceImpl extends ServiceImpl<SalesOrderMapper, SalesOrder> implements ISalesOrderService {

    private final SalesOrderMapper salesOrderMapper;
    private final CustomerMapper customerMapper;
    private final SysUserMapper userMapper;

    @Override
    public TableDataInfo<SalesOrderVo> selectPageList(SalesOrderSearch salesOrderSearch, PageQuery pageQuery) {
        Page<SalesOrderVo> page =
                salesOrderMapper.selectPageList(pageQuery.build(), buildQueryWrapper(salesOrderSearch));
        // 填充状态描述
        if (page.getRecords() != null) {
            page.getRecords().forEach(vo -> {

                Long customerId = vo.getCustomerId();
                Long salespersonId = vo.getSalespersonId();
                if (customerId != null) {
                    vo.setCustomerName(customerMapper.selectById(customerId).getCustomerName());
                }
                if (salespersonId != null) {
                    vo.setSalespersonName(userMapper.selectById(salespersonId).getNickName());
                }
                vo.setStatusDesc(SalesOrderStatusEnum.getDescByCode(vo.getStatus()));
            });
        }
        return TableDataInfo.build(page);
    }

    @Override
    public List<SalesOrderVo> searchList(SalesOrderSearch salesOrderSearch) {
        Wrapper<SalesOrder> wrapper = this.buildQueryWrapper(salesOrderSearch);
        List<SalesOrderVo> list = salesOrderMapper.selectSalesOrderList(wrapper);
        // 填充状态描述
        if (list != null) {
            list.forEach(vo -> {
                vo.setStatusDesc(SalesOrderStatusEnum.getDescByCode(vo.getStatus()));
            });
        }
        return list;
    }

    @Override
    public SalesOrderVo selectSalesOrderById(Long salesOrderId) {
        SalesOrderVo salesOrderVo = salesOrderMapper.selectSalesOrderDetail(salesOrderId);
        if (salesOrderVo != null) {
            salesOrderVo.setStatusDesc(SalesOrderStatusEnum.getDescByCode(salesOrderVo.getStatus()));
        }
        return salesOrderVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertSalesOrder(SalesOrder salesOrder) {
        // 生成销售单号
        String salesOrderNo = generateSalesOrderNo();
        salesOrder.setSalesOrderNo(salesOrderNo);

        // 自动填充销售人员ID
        fillSalespersonInfo(salesOrder);
        // 设置默认状态为完结
        if (salesOrder.getStatus() == null) {
            salesOrder.setStatus(SalesOrderStatusEnum.COMPLETED.getCode());
        }

        if (!this.save(salesOrder)) {
            throw new ServiceException("创建销售订单失败");
        }

        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateSalesOrder(SalesOrder salesOrder) {
        if (salesOrder.getSalesOrderId() == null) {
            throw new ServiceException("销售订单ID不能为空");
        }

        if (!this.updateById(salesOrder)) {
            throw new ServiceException("更新销售订单失败");
        }

        return 1;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteSalesOrderById(Long salesOrderId) {
        return this.removeById(salesOrderId) ? 1 : 0;
    }

    /**
     * 生成销售单号
     * 格式：SO + yyyyMMdd + 6位序号
     * 示例：SO20241201000001
     */
    private String generateSalesOrderNo() {
        String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String prefix = "SO" + date;

        // 查询今天最大的销售单号
        LambdaQueryWrapper<SalesOrder> wrapper = Wrappers.lambdaQuery();
        wrapper.likeRight(SalesOrder::getSalesOrderNo, prefix)
                .orderByDesc(SalesOrder::getSalesOrderNo)
                .last("LIMIT 1");

        SalesOrder lastOrder = this.getOne(wrapper);

        int sequence = 1;
        if (lastOrder != null && StrUtil.isNotBlank(lastOrder.getSalesOrderNo())) {
            String lastNo = lastOrder.getSalesOrderNo();
            String lastSequence = lastNo.substring(prefix.length());
            try {
                sequence = Integer.parseInt(lastSequence) + 1;
            } catch (NumberFormatException e) {
                sequence = 1;
            }
        }

        return prefix + String.format("%06d", sequence);
    }

    /**
     * 填充销售人员信息
     */
    private void fillSalespersonInfo(SalesOrder salesOrder) {
        try {
            // 获取当前登录用户
            var loginUser = LoginHelper.getLoginUser();
            if (loginUser != null) {
                // 设置销售人员ID（当前登录用户ID）
                salesOrder.setSalespersonId(loginUser.getUserId());
            }
        } catch (Exception e) {
            // 获取用户信息失败时记录日志，但不影响主流程
            log.error("自动填充销售人员信息失败", e);
        }
    }

    /**
     * 构建查询条件
     */
    private Wrapper<SalesOrder> buildQueryWrapper(SalesOrderSearch salesOrderSearch) {
        Map<String, Object> params = salesOrderSearch.getParams();
        // 使用 QueryWrapper 并指定表别名
        LambdaQueryWrapper<SalesOrder> wrapper = Wrappers.lambdaQuery();
        // 使用表别名 so. 前缀
        if (StringUtils.isNotBlank(salesOrderSearch.getSalesOrderNo())) {
            wrapper.like(SalesOrder::getSalesOrderNo, salesOrderSearch.getSalesOrderNo());
        }
        if (ObjectUtil.isNotNull(salesOrderSearch.getSalespersonId())) {
            wrapper.eq(SalesOrder::getSalesOrderId, salesOrderSearch.getSalespersonId());
        }
        if (ObjectUtil.isNotNull(salesOrderSearch.getCustomerId())) {
            wrapper.eq(SalesOrder::getCustomerId, salesOrderSearch.getCustomerId());
        }
        if (ObjectUtil.isNotNull(salesOrderSearch.getStatus())) {
            wrapper.eq(SalesOrder::getStatus, salesOrderSearch.getStatus());
        }
        if (params.get("beginTime") != null && params.get("endTime") != null) {
            wrapper.between(SalesOrder::getCreateTime, params.get("beginTime"), params.get("endTime"));
        }
        wrapper.orderByDesc(SalesOrder::getCreateTime);
        return wrapper;
    }

    @Override
    public SalesStatisticsVo getSalesStatistics(SalesStatisticsSearch search) {
        // 根据统计类型和日期/年份计算起止时间
        java.sql.Date beginTime;
        java.sql.Date endTime;

        LocalDate targetDate = LocalDate.now();
        // 默认按月统计，使用当前日期或传入的日期
        if (search.getDate() != null) {
            targetDate = search.getDate();
        }
        if (search.getStatisticsType() == null || "month".equals(search.getStatisticsType())) {
            // 该月的第一天和最后一天
            beginTime = java.sql.Date.valueOf(targetDate.withDayOfMonth(1));
            endTime = java.sql.Date.valueOf(targetDate.withDayOfMonth(targetDate.lengthOfMonth()));
        } else if ("week".equals(search.getStatisticsType())) {
            // 该周的第一天（周一）和最后一天（周日）
            int dayOfWeek = targetDate.getDayOfWeek().getValue(); // 1=Monday, 7=Sunday
            beginTime = java.sql.Date.valueOf(targetDate.minusDays(dayOfWeek - 1));
            endTime = java.sql.Date.valueOf(targetDate.plusDays(7 - dayOfWeek));
        } else if ("quarter".equals(search.getStatisticsType())) {
            // 按季度统计
            // 该季度的第一天和最后一天
            int month = targetDate.getMonthValue();
            int quarter = (month - 1) / 3;
            int quarterStartMonth = quarter * 3 + 1;
            int quarterEndMonth = quarterStartMonth + 2;
            beginTime = java.sql.Date.valueOf(LocalDate.of(targetDate.getYear(), quarterStartMonth, 1));
            LocalDate quarterEndDate = LocalDate.of(targetDate.getYear(), quarterEndMonth, 1);
            endTime = java.sql.Date.valueOf(quarterEndDate.withDayOfMonth(quarterEndDate.lengthOfMonth()));
        } else if ("year".equals(search.getStatisticsType())) {
            // 按年统计
            int targetYear = search.getYear() != null ? search.getYear() : LocalDate.now().getYear();
            beginTime = java.sql.Date.valueOf(LocalDate.of(targetYear, 1, 1));
            endTime = java.sql.Date.valueOf(LocalDate.of(targetYear, 12, 31));
        } else {
            // 默认按月统计
            beginTime = java.sql.Date.valueOf(targetDate.withDayOfMonth(1));
            endTime = java.sql.Date.valueOf(targetDate.withDayOfMonth(targetDate.lengthOfMonth()));
        }

        // 查询总体统计数据
        SalesStatisticsVo statistics = salesOrderMapper.selectSalesStatisticsSummary(
                beginTime,
                endTime,
                search.getSalespersonId());

        if (statistics == null) {
            statistics = new SalesStatisticsVo();
            statistics.setTotalSalesAmount(BigDecimal.ZERO);
            statistics.setCompletedCustomerCount(0);
            statistics.setCompletedOrderCount(0);
            statistics.setRefundedOrderCount(0);
            statistics.setTotalOrderCount(0);
            statistics.setSuccessRate(BigDecimal.ZERO);
        }

        // 计算成交率
        if (statistics.getTotalOrderCount() != null && statistics.getTotalOrderCount() > 0) {
            BigDecimal successRate = new BigDecimal(statistics.getCompletedOrderCount())
                    .divide(new BigDecimal(statistics.getTotalOrderCount()), 4, java.math.RoundingMode.HALF_UP)
                    .multiply(new BigDecimal(100))
                    .setScale(2, java.math.RoundingMode.HALF_UP);
            statistics.setSuccessRate(successRate);
        } else {
            statistics.setSuccessRate(BigDecimal.ZERO);
        }

        // 查询时间序列数据
        List<SalesStatisticsVo.TimeSeriesData> timeSeriesData = salesOrderMapper.selectSalesStatisticsTimeSeries(
                beginTime,
                endTime,
                search.getSalespersonId(),
                search.getStatisticsType());
        statistics.setTimeSeriesData(timeSeriesData != null ? timeSeriesData : new java.util.ArrayList<>());

        // 查询销售人员数据
        List<SalesStatisticsVo.SalespersonData> salespersonData = salesOrderMapper.selectSalesStatisticsBySalesperson(
                beginTime,
                endTime,
                search.getSalespersonId());
        statistics.setSalespersonData(salespersonData != null ? salespersonData : new java.util.ArrayList<>());

        return statistics;
    }
}

